/*
 * sigwaitinfo.c
 *
 *  Created on: Jul 15, 2011
 *      Author: makkalot
 */


#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <fibthread.h>
#include <unistd.h>
#include <errno.h>

void * foo(void *arg);
void * bar(void *arg);
void * sigint(void *arg);

int main(int argc, char *argv[]){

	sigset_t th_sigmask;
	int result, error;
	fibthread_t tfoo, tbar, tsig;
	fibthread_attr_t tattr;

	/* Now start waiting for threads to finish */
	if ((error = fibthread_attr_init(&tattr)) != 0)
		fprintf(stderr, "Failed to create attribute object: %s\n",strerror(error));
	else if ((error = fibthread_attr_setdetachstate(&tattr,FIBTHREAD_CREATE_DETACHED)) != 0)
		fprintf(stderr, "Failed to set attribute state to detached: %s\n",
						  strerror(error));

	/* First we block all of the signals so
	 * the created children inherits them */

	sigfillset(&th_sigmask);
	if((result = fibthread_sigmask(SIG_SETMASK, &th_sigmask, NULL)) != 0)
		fprintf(stderr, "fibthread_sigmask : %s \n",strerror(result));

	/* Now create the threads */
	if((result = fibthread_create(&tsig, &tattr, sigint, NULL)) != 0)
			fprintf(stderr, "fibthread_create : %s \n",strerror(result));
	if((result = fibthread_create(&tfoo, &tattr, foo, (void *)&tsig)) != 0)
			fprintf(stderr, "fibthread_create : %s \n",strerror(result));
	if((result = fibthread_create(&tbar, &tattr, bar, NULL)) != 0)
			fprintf(stderr, "fibthread_create : %s \n",strerror(result));



	printf("Main thread is exiting ... \n");
	fibthread_exit(0);

	return 0;
}


void * foo(void *arg){

	fibthread_t *tsig;
	int i = 0;

	tsig = (fibthread_t *)arg;

	for(i = 0; i < 5; i++){
		printf("In foo ... \n");
		fibthread_kill(*tsig, SIGINT);
		sleep(3);
		fibthread_yield();
	}

	return NULL;
}

void * bar(void *arg){
	int i = 0;

	for(i = 0; i < 5; i++){
		printf("In bar ... \n");
		sleep(3);
		fibthread_yield();
	}

	return NULL;
}

void * sigint(void *arg){
	int result, i = 0;
	sigset_t sigint_set;

	sigemptyset(&sigint_set);
	sigaddset(&sigint_set, SIGINT);

	for(i = 0; i < 10; i++){
		printf("In sigint ...");
		if(fibthread_sigwait(&sigint_set, &result) != 0){
			printf("fibthread_sigwait error \n");
			break;
		}

		printf("SIGINT Received : %d \n",result);
		sleep(3);
		if(fibthread_yield() != 0)
			break;
	}

	return NULL;
}
